package com.geostar.constructionland.analyse.service.adjust;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.geostar.constructionland.analyse.agri.AdjustAgri;
import com.geostar.constructionland.analyse.entity.alyresult.AlyResultYphx;
import com.geostar.constructionland.analyse.entity.alyresult.tzhdlgdfx.AlyResultGdZlDb;
import com.geostar.constructionland.analyse.entity.statistics.SticDlfxTzh;
import com.geostar.constructionland.analyse.mapper.adjust.AdjustMapper;
import com.geostar.constructionland.analyse.mapper.sptalyresult.AlyResultGdzldbMapper;
import com.geostar.constructionland.analyse.mapper.sptalyresult.AlyResultYphxMapper;
import com.geostar.constructionland.analyse.mapper.statistics.SticDlfxTzhMapper;
import com.geostar.constructionland.analyse.service.BaseAdjustService;
import com.geostar.constructionland.analyse.service.analyseresult.SticDlfxTzhService;
import com.geostar.constructionland.analyse.service.analyseresult.TzhDlGdFxService;
import com.geostar.constructionland.common.entity.biz.PieceLandInfo;
import com.geostar.constructionland.common.entity.logs.JsydFxrz;
import com.geostar.constructionland.common.entity.response.LandInfo;
import com.geostar.constructionland.common.entity.response.model.AdjustModel;
import com.geostar.constructionland.common.global.AnalyseType;
import com.geostar.constructionland.common.global.LandCode;
import com.geostar.constructionland.common.mapper.biz.PieceLandInfoMapper;
import com.geostar.constructionland.common.mapper.logs.JsydFxrzMaper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 调整后耕地平差算法
 *
 * @Author:Yell
 * @Since:2020-8-10 15:42
 */
@Component
@Slf4j
public class TzhDlGdAdjust implements IAdjust {
    @Autowired
    BaseAdjustService adjustService;
    @Autowired
    SticDlfxTzhService sticDlfxTzhService;
    @Autowired
    AdjustMapper adjustMapper;
    @Autowired
    PieceLandInfoMapper landInfoMapper;
    @Autowired
    AlyResultGdzldbMapper alyResultGdzldbMapper;
    @Autowired
    TzhDlGdFxService tzhDlGdFxService;
    @Autowired
    SticDlfxTzhMapper sticDlfxTzhMapper;
    @Autowired
    JsydFxrzMaper jsydFxrzMaper;
    @Autowired
    AlyResultYphxMapper yphxMapper;
    /**
     * 小数省略位
     */
    private int iScale;
    /**
     * 阈值
     */
    private double adjustThreshold;
    /**
     * 平差单位
     */
    private double adjustUnit;
    private AdjustModel adjustModel;

    @Override
    public List<LandInfo> adjust(AdjustModel adjustModel) throws Exception {
        /***
         * 部分面积计算方式
         * 耕地面积 = 水田面积 + 旱地面积 + 水浇地面积
         * 农用地面积 = 耕地面积 + 园地面积 + 林地面积 + 其他农用地面积
         */
        /**赋值**/
        iScale = adjustModel.getAdjustAgrVersion().getIScale();
        adjustThreshold = adjustModel.getAdjustAgrVersion().getAdjustThreshold();
        adjustUnit = adjustModel.getAdjustAgrVersion().getAdjustUnit();
        this.adjustModel = adjustModel;
        /***总体进行判断*/
        /**   select sum(dkmj_ys) dkmj from jsyd_dkxx where kcdjid in
         *     (select kcdjid from jsyd_xmdkgx where ywid=#{ywid})")
         * */

        double totalDkmjYs = tzhDlGdFxService.getTotalDkmjYs(adjustModel.getYwid());
        /**select sum(zymj_ys) zymjys from jsyd_fx_dlfx_tj_tzh where fxbs=#{fxbs}**/
//        select sum(zymj_ys) zymjys from jsyd_fx_dlfx_tj_tzh where fxbs=#{fxbs,jdbcType=VARCHAR}
        double totalZymjYs = tzhDlGdFxService.getTotalZymjScaled(adjustModel.getFxbs());
        log.info("调整后地类分析，地块面积总和:{},占压面积总和:{},差值:{},阈值:{}", totalDkmjYs, totalZymjYs,
                Math.abs(totalDkmjYs - totalZymjYs), adjustModel.getAdjustAgrVersion().getAdjustThreshold());
        if (Math.abs(totalDkmjYs - totalZymjYs) >= adjustModel.getAdjustAgrVersion().getAdjustThreshold()) {
            log.info("不需要进行平差;");
            return null;
        }
        /**水田平差*/
        double pdyAdjust = pdy_adjust();
        /**水浇地和旱地平差*/
        double farmlandAjust = dryIrg_adjust(pdyAdjust);
        /***可调整平差*/
        double ktzFarmAdjust = ktz_adjust(farmlandAjust);
        /**建设用地平差*/
        buildAdjust(ktzFarmAdjust);
        /**剩余平差*/
        restAdjust();
        /**剩余原始总面积平差*/
        rest_adjust_ori();
        /**可调整数据调整*/
        dataHandler();
        /**耕地二次平差*/
        gdzl_adjust();
        /**统计耕地质量分析结果*/
        sticGdZlFxTj();
        /**报批红线平差*/
//        yphxAdjust();
        return null;
    }

    /**
     * 已批红线平差
     */
    public void yphxAdjust() throws Exception {
        /*获取分析标识*/
        String cdyphxFxbs = getFxbs(AnalyseType.CDYPHXFX.getCode(), adjustModel.getYwid());
        /*获取已批红线内容*/
        List<AlyResultYphx> yphxes =
                yphxMapper.selectList(new QueryWrapper<AlyResultYphx>().eq("fxbs", cdyphxFxbs));
        if (CollectionUtils.isEmpty(yphxes)) {
            /*获取已批红线分析分析标识*/
            String yphxFxbs = getFxbs(AnalyseType.YPHXFX.getCode(), adjustModel.getYwid());
            if (StringUtils.isNotBlank(yphxFxbs)) {
                /*查询报批红线内容*/
                QueryWrapper<SticDlfxTzh> sticDlfxTzhQw = new QueryWrapper<>();
                sticDlfxTzhQw.eq("fxbs", adjustModel.getFxbs());
                sticDlfxTzhQw.eq("bphxfxid", "true");
                sticDlfxTzhQw.eq("ktzmj", "0");
                List<SticDlfxTzh> bphxSticList = sticDlfxTzhMapper.selectList(sticDlfxTzhQw);
                /*报批红线调整后地类分析总值*/
                BigDecimal totalPbhxDlfxTj = bphxSticList.stream()
                        .map(s -> BigDecimal.valueOf(s.getZymj())).reduce(BigDecimal.ZERO, BigDecimal::add);
                /*查询已批红线四舍五入后合计总值**/
                List<AlyResultYphx> yphxList = yphxMapper.selectList(new QueryWrapper<AlyResultYphx>().eq("fxbs", yphxFxbs));
                /*已批红线分析总值*/
                BigDecimal totalYpys = yphxList.stream()
                        .map(s -> BigDecimal.valueOf(s.getZymj())).reduce(BigDecimal.ZERO, BigDecimal::add);
                double adjustTotal = totalYpys.subtract(totalPbhxDlfxTj).doubleValue();
                if (Math.abs(adjustTotal) >= adjustThreshold) {
                    /**大于阈值，抛出异常**/
                    throw new Exception(".差值大于阈值,差值:" + adjustTotal + ",阈值:" + adjustThreshold);
                }
                List<AlyResultYphx> yphxAdjustList = yphxMapper.getSortedBphxList(yphxFxbs, adjustTotal > 0 ? "asc" : "desc");
                List<LandInfo> landInfoAdjut =
                        yphxAdjustList.stream().map(yphx -> {
                            LandInfo landInfo = new LandInfo();
                            landInfo.setFxId(yphx.getFxid());
                            landInfo.setZymj_ys(yphx.getZymj());
                            return landInfo;
                        }).collect(Collectors.toList());
                List<LandInfo> landInfos_adjusted = AdjustAgri.adjust(landInfoAdjut, Math.abs(adjustTotal), adjustUnit);
                /*更新已批红线数据*/
                landInfos_adjusted.stream().forEach(ld -> {
                    yphxMapper.updateAdjustZymj(ld.getFxId(), ld.getZymj_adjusted());
                });
            }
        }
    }


    /**
     * 获取分析表示
     *
     * @return
     */
    private String getFxbs(String fxlx, String ywid) {
        QueryWrapper<JsydFxrz> jsydQw = new QueryWrapper<>();
        jsydQw.eq("fxlx", fxlx);
        jsydQw.eq("ywid", ywid);
        JsydFxrz jsydFxrz = jsydFxrzMaper.selectOne(jsydQw);
        /*获取分析标识*/
        String cdyphxFxbs = jsydFxrz.getFxbs();
        return cdyphxFxbs;
    }

    /**
     * 统计耕地质量分析
     */
    private void sticGdZlFxTj() {
        tzhDlGdFxService.saveGdZlfxTj(adjustModel.getFxbs());
    }

    /***
     * 耕地二次平差
     */
    private void gdzl_adjust() throws Exception {
        /**查询耕地信息*/
        List<Map> gdList = sticDlfxTzhService.getGdInfos(adjustModel.getFxbs());
        for (Map map : gdList) {
            /***耕地合计_原始*/
            BigDecimal gdhj_ys = new BigDecimal((map.get("GDHJ_YS") == null || StringUtils.isBlank(map.get("GDHJ_YS").toString())) ? "0" : map.get("GDHJ_YS").toString());
            /***地类面积_原始*/
            BigDecimal dlmj_ys = new BigDecimal((map.get("DLMJ_YS") == null || StringUtils.isBlank(map.get("DLMJ_YS").toString())) ? "0" : map.get("DLMJ_YS").toString());
            /****/
            BigDecimal gdhj_sswr = new BigDecimal((map.get("GDHJ_SSWR") == null || StringUtils.isBlank(map.get("GDHJ_SSWR").toString())) ? "0" : map.get("GDHJ_SSWR").toString());
            /***地类面积 平差后*/
            BigDecimal dlmj_pch = new BigDecimal((map.get("DLMJ_PCH") == null || StringUtils.isBlank(map.get("DLMJ_PCH").toString())) ? "0" : map.get("DLMJ_PCH").toString());
            BigDecimal dlSubGd = BigDecimal.ZERO;
            if (gdhj_ys.subtract(dlmj_ys).compareTo(new BigDecimal("0.5")) > 0) {
                /**如果gdhj_ys-dlmj_ys>0.5 异常**/
                throw new Exception("gdhj_ys-dlmj_ys>0.5");
            } else if (gdhj_ys.subtract(dlmj_ys).compareTo(new BigDecimal(-1)) > 0) {
                /**如果-1 < gdhj_ys-dlmj_ys < 0.5  调用方法  参数为 gdhj_sswr-dlmj_pch**/
                dlSubGd = gdhj_sswr.subtract(dlmj_pch);
            } else {
                /**否则，gdhj_sswr-(gdhj_ys四舍五入)**/
                BigDecimal gdhj_ys_scale = gdhj_ys.setScale(0, BigDecimal.ROUND_HALF_UP);
                dlSubGd = gdhj_sswr.subtract(gdhj_ys_scale);
            }
            List<AlyResultGdZlDb> gdZlDbs = alyResultGdzldbMapper.getGdFxneedPc(map.get("DLID").toString(), dlSubGd.doubleValue() > 0 ? "asc" : "desc");
            if (CollectionUtils.isEmpty(gdZlDbs)) {
                continue;
            }
            List<LandInfo> landInfos = gdZlDbs.stream().map(gdzldb -> {
                LandInfo landInfo = new LandInfo();
                landInfo.setFxId(gdzldb.getFxid());
                landInfo.setZymj_ys(gdzldb.getZymj());
                landInfo.setZymj_adjusted(gdzldb.getZymj());
                return landInfo;
            }).collect(Collectors.toList());
            List<LandInfo> landInfos_adjusted = AdjustAgri.adjust(landInfos, dlSubGd.doubleValue(), adjustUnit);
            landInfos_adjusted.stream().forEach(landInfo_adjusted -> {
                alyResultGdzldbMapper.updateGdzl(landInfo_adjusted.getZymj_adjusted() + "", landInfo_adjusted.getFxId());
            });
        }
    }

    /**
     * 保存可调整数据
     */
    private void dataHandler() {
        /**批量插入*/
        List<SticDlfxTzh> ktzSticDlfxTzh = sticDlfxTzhService.getKtzSticDlfxTzh(adjustModel.getFxbs());
        sticDlfxTzhService.saveBatch(ktzSticDlfxTzh);
        /**更新调整后地类分析，更新 ktzmj 为2的数据 为 ktzmj 为0**/
        sticDlfxTzhService.updateSticKtzmjAdjust(adjustModel.getFxbs());
        /**查询地块信息*/
        List<PieceLandInfo> landInfos =
                landInfoMapper.getPieLandInfosByYwid(adjustModel.getYwid());
        landInfos.forEach(landInfo -> {
            double dkmj_adjusted = sticDlfxTzhService.getAdjustedTotalMjByDkxx(adjustModel.getFxbs(), landInfo.getDkid());
            if (dkmj_adjusted >= 0) {
                landInfoMapper.updateAdjustDkmj(landInfo.getDkid(), dkmj_adjusted);
            }
        });
    }

    /**
     * 剩余原始总面积平差
     */
    private void rest_adjust_ori() throws Exception {
        /**获取原始总面积*/
        BigDecimal dkmj_ys = new BigDecimal(adjustMapper.getDkYsMj(adjustModel.getYwid())).setScale(0, BigDecimal.ROUND_HALF_UP);
        /**地类面积平差后*/
        BigDecimal dlmj_adjusted = new BigDecimal(adjustMapper.getAdjustedDlfxMj(adjustModel.getFxbs()));
        BigDecimal restAdjustOrg_totalAdjust = dlmj_adjusted.subtract(dkmj_ys);

        List<SticDlfxTzh> restAdjustOriList = sticDlfxTzhService.getRestAdjustOri(adjustModel.getFxbs());
        adjustAndUpdate(restAdjustOriList, restAdjustOrg_totalAdjust.doubleValue());
    }


    /***
     * 剩余平差 保持总量与整体地块面积相同
     *
     */
    private double restAdjust() throws Exception {
        /**查询地块面积之和**/
        double totalDkmjYs = sticDlfxTzhMapper.getTotalDkmjYs(adjustModel.getYwid());
        BigDecimal total_fact = BigDecimal.valueOf(totalDkmjYs).setScale(iScale, RoundingMode.HALF_UP);

        /***所有调整后统计地类分析 占压面积*/
        List<SticDlfxTzh> totalSticDlfxTzh = sticDlfxTzhService.list(new QueryWrapper<SticDlfxTzh>().eq("fxbs", adjustModel.getFxbs()));
        BigDecimal total_exp = totalSticDlfxTzh.stream().map(s -> BigDecimal.valueOf(s.getZymj())).reduce(BigDecimal.ZERO, BigDecimal::add);

        /**获取平差值*/
        double adjustTotal = total_exp.subtract(total_fact).doubleValue();
        if (Math.abs(adjustTotal) >= adjustThreshold) {
            /**大于阈值，抛出异常**/
            throw new Exception("调整后耕地分析剩余平差中.差值大于阈值,差值:" + adjustTotal + ",阈值:" + adjustThreshold);
        }
        List<SticDlfxTzh> totalFieldSorted =
                sticDlfxTzhService.getSortedRestFields(adjustModel.getFxbs(), adjustTotal > 0 ? "asc" : "desc");
        adjustAndUpdate(totalFieldSorted, adjustTotal);
        return total_fact.doubleValue();
    }

    /**
     * 建设用地平差
     *
     * @param ktz_farm_adjust 可调整和耕地平差后总值
     * @return
     * @throws Exception
     */
    private double buildAdjust(double ktz_farm_adjust) throws Exception {
        /**查询建设用地加可调整加耕地数据*/
        List<SticDlfxTzh> build_ktz_farm_FieldData =
                sticDlfxTzhService.getKtzFarmBuildList(adjustModel.getFxbs());
        /***获取建设用地的调整后分析数据*/
        List<SticDlfxTzh> buildFieldData = build_ktz_farm_FieldData.stream().filter(s ->
                LandCode.BUILDING_LAND.getCode().equals(s.getDlbm1())).collect(Collectors.toList());
        /***如果调整后分析 -> 建设用地数据 为空,则直接返回*/
        if (CollectionUtils.isEmpty(buildFieldData)) {
            return ktz_farm_adjust;
        }
        /**农田和可调整以及建设用地面积实际值**/
        BigDecimal build_ktz_farm_fact_total = build_ktz_farm_FieldData.stream()
                .map(s -> BigDecimal.valueOf(s.getZymjYs()))
                .reduce(BigDecimal.ZERO, BigDecimal::add)
                .setScale(iScale, BigDecimal.ROUND_HALF_UP);
        /***建设用地实际值*/
        BigDecimal build_fact_total = build_ktz_farm_fact_total.subtract(new BigDecimal(ktz_farm_adjust));

        /***建设用地展示值*/
        BigDecimal build_ext_total = buildFieldData.stream()
                .map(s -> BigDecimal.valueOf(s.getZymjYs()).setScale(iScale, BigDecimal.ROUND_HALF_UP))
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        /**获取平差值*/
        double buildAdjustTotal = build_ext_total.subtract(build_fact_total).doubleValue();
        if (Math.abs(buildAdjustTotal) >= adjustThreshold) {
            /**大于阈值，抛出异常**/
            throw new Exception("调整后耕地分析建设用地平差中.差值大于阈值,差值:" + buildAdjustTotal + ",阈值:" + adjustThreshold);
        }
        /**排序*/
        /**通过SQL对平差数据进行排序**/
        List<SticDlfxTzh> buildFieldSorted =
                sticDlfxTzhService.getSortedBuildFields(adjustModel.getFxbs(), buildAdjustTotal > 0 ? "asc" : "desc");
        adjustAndUpdate(buildFieldSorted, buildAdjustTotal);
        return build_ktz_farm_fact_total.doubleValue();
    }

    /**
     * 可调整面积平差
     *
     * @param farmlandAdjustTotal 耕地平差后总值
     * @return 耕地+可调整 平差总值
     */
    private double ktz_adjust(double farmlandAdjustTotal) throws Exception {
        log.debug("------可调整面积平差开始--------");
        String[] farmLandCode = {LandCode.PADDY_FIELD.getCode(), LandCode.DRY_LAND.getCode(), LandCode.IRRIGATED_LAND.getCode()};
        /**查询可调整加耕地数据*/
        List<SticDlfxTzh> ktz_farm_FieldData =
                sticDlfxTzhService.list(new QueryWrapper<SticDlfxTzh>()
                        .or(wrapper -> wrapper
                                .in("dlbm", farmLandCode)
                                .or()
                                .gt("ktzmj", 0))
                        .eq("fxbs", adjustModel.getFxbs()));
        /***可调整数据*/
        List<SticDlfxTzh> ktzFieldData = ktz_farm_FieldData.stream()
                .filter(s -> s.getKtzmj() > 0).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(ktzFieldData)) {
            /***可调整为空*/
            return farmlandAdjustTotal;
        }
        /***可调整与农地实实际值*/
        BigDecimal ktz_farm_fact_total = ktz_farm_FieldData.stream()
                .map(s -> BigDecimal.valueOf(s.getZymjYs()))
                .reduce(BigDecimal.ZERO, BigDecimal::add)
                .setScale(iScale, BigDecimal.ROUND_HALF_UP);
        BigDecimal ktz_fact_total = ktz_farm_fact_total.subtract(new BigDecimal(farmlandAdjustTotal));

        /***可调整和耕地展示值*/
        BigDecimal ktz_exp_total = ktzFieldData.stream()
                .map(s -> BigDecimal.valueOf(s.getZymjYs()).setScale(iScale, BigDecimal.ROUND_HALF_UP))
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        double ktz_adjust_total = ktz_exp_total.subtract(ktz_fact_total).doubleValue();
        log.info("可调整面积,实际值:{},页面展示值:{},差值{}，阈值{}", ktz_fact_total, ktz_exp_total, ktz_adjust_total, adjustThreshold);
        if (Math.abs(ktz_adjust_total) >= adjustThreshold) {
            /**大于阈值，抛出异常**/
            throw new Exception("调整后耕地分析平差可调整平差中.差值大于阈值,差值:" + ktz_adjust_total + ",阈值:" + adjustThreshold);
        }
        /**通过SQL对平差数据进行排序**/
        List<SticDlfxTzh> ktzFieldSorted =
                sticDlfxTzhService.getSortedKtzFields(adjustModel.getFxbs(), ktz_adjust_total > 0 ? "asc" : "desc");
        adjustAndUpdate(ktzFieldSorted, ktz_adjust_total);
        return ktz_farm_fact_total.doubleValue();
    }

    /**
     * 水浇地和旱地平差
     *
     * @return 农用地平差后总值
     */
    private double dryIrg_adjust(double pdyAdjustTotal) throws Exception {
        log.debug("------水浇地和旱地平差开始--------");
        /**查询耕地数据*/
        /**耕地 = 水田 +  水浇地 + 旱地 即 地类编码 为 011 + 012 + 013 */
        List<SticDlfxTzh> farmlandFieldData =
                sticDlfxTzhService.list(new QueryWrapper<SticDlfxTzh>()
                        .or(wrapper -> wrapper
                                .eq("dlbm", LandCode.DRY_LAND.getCode())
                                .or()
                                .eq("dlbm", LandCode.IRRIGATED_LAND.getCode())
                                .or()
                                .eq("dlbm", LandCode.PADDY_FIELD.getCode()))
                        .eq("fxbs", adjustModel.getFxbs()));

        /***查找水浇地+旱地数据*/
        List<SticDlfxTzh> dryIrgFieldData = farmlandFieldData.stream()
                .filter(s -> LandCode.DRY_LAND.getCode().equals(s.getDlbm())
                        || LandCode.IRRIGATED_LAND.getCode().equals(s.getDlbm())).collect(Collectors.toList());

        /**如果水浇地和旱地数据不为空**/
        if (CollectionUtils.isEmpty(dryIrgFieldData)) {
            log.info("水浇地和旱地为空");
            return pdyAdjustTotal;
        }

        /**耕地原始占压面积之和 四舍五入*/
        BigDecimal farmland_fact_total = farmlandFieldData.stream()
                .map(s -> BigDecimal.valueOf(s.getZymjYs()))
                .reduce(BigDecimal.ZERO, BigDecimal::add)
                .setScale(iScale, BigDecimal.ROUND_HALF_UP);

        /**旱地和水浇地实际值 = (耕地原始占压面积之和).setScale(scale,half_up) - (水田占压面积之和,即水田平差返回的平差后的总值） */
        BigDecimal dryIrg_fact_total = farmland_fact_total.subtract(new BigDecimal(pdyAdjustTotal));

        /**旱地和水浇地页面展示总值*/
        BigDecimal dryIrg_exp_total = dryIrgFieldData.stream()
                .map(s -> BigDecimal.valueOf(s.getZymjYs()).setScale(iScale, BigDecimal.ROUND_HALF_UP))
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        /***平差总值*/
        double dryIrg_adjust_total = dryIrg_exp_total.subtract(dryIrg_fact_total).doubleValue();

        log.info("旱地水浇地平差,实际值:{},页面展示值:{},差值{}，阈值{}", dryIrg_fact_total, dryIrg_exp_total, dryIrg_adjust_total, adjustThreshold);
        if (Math.abs(dryIrg_adjust_total) >= adjustThreshold) {
            /**大于阈值，抛出异常**/
            throw new Exception("调整后耕地分析平差水浇地旱地平差中.差值大于阈值,差值:" + dryIrg_adjust_total + ",阈值:" + adjustThreshold);
        }
        /**通过SQL对平差数据进行排序**/
        List<SticDlfxTzh> dryIrgFieldSorted =
                sticDlfxTzhService.getSortedDryIrgFields(adjustModel.getFxbs(), dryIrg_adjust_total > 0 ? "asc" : "desc");
        adjustAndUpdate(dryIrgFieldSorted, dryIrg_adjust_total);
        return farmland_fact_total.doubleValue();
    }


    /**
     * 水田平差
     *
     * @return 水田平差后总值
     */
    private double pdy_adjust() throws Exception {
        log.debug("------水田平差------");
        /**查找地类编码我011（即水田）的调整后地类数据**/
        List<SticDlfxTzh> pdyFieldsData =
                sticDlfxTzhService.list(new QueryWrapper<SticDlfxTzh>()
                        .eq("dlbm", LandCode.PADDY_FIELD.getCode())
                        .eq("fxbs", adjustModel.getFxbs()));
        /**如果水田为空**/
        if (CollectionUtils.isEmpty(pdyFieldsData)) {
            log.info("查询不到地类编码为011(水田)的数据");
            return 0;
        }
        /**原始占压面积四舍五入值的总和**/
        BigDecimal pdy_express_total = pdyFieldsData.stream().map(s -> BigDecimal.valueOf(s.getZymjYs())
                .setScale(iScale, BigDecimal.ROUND_HALF_UP))
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        /**原始占压面积总和的四舍五入值**/
        BigDecimal pdy_fact_total = pdyFieldsData.stream().map(s -> BigDecimal.valueOf(s.getZymjYs()))
                .reduce(BigDecimal.ZERO, BigDecimal::add)
                .setScale(iScale, BigDecimal.ROUND_HALF_UP);
        /**差值*/
        double pdy_totalAdjust = pdy_express_total.subtract(pdy_fact_total).doubleValue();
        log.info("水田平差,实际值:{},展示值:{},差值{}，阈值{}", pdy_express_total, pdy_fact_total, pdy_express_total, adjustThreshold);
        if (Math.abs(pdy_totalAdjust) >= adjustThreshold) {
            /**大于阈值，抛出异常**/
            throw new Exception("调整后耕地分析平差水田平差中.差值大于阈值,差值:" + pdy_totalAdjust + ",阈值:" + adjustThreshold);
        }
        /**通过SQL对平差数据进行排序**/
        List<SticDlfxTzh> pdyFieldSorted =
                sticDlfxTzhService.getSortedPdyFields(adjustModel.getFxbs(), pdy_totalAdjust > 0 ? "asc" : "desc");
        adjustAndUpdate(pdyFieldSorted, pdy_totalAdjust);
        return pdy_fact_total.doubleValue();
    }


    /***
     * 平差 更新 数据
     * @param fieldSorted 排序后数据
     * @param adjustTotal 平差值
     * @throws Exception
     */
    public void adjustAndUpdate(List<SticDlfxTzh> fieldSorted, double adjustTotal) throws Exception {
        List<LandInfo> landInfos_adjusted =
                AdjustAgri.adjust(fieldSorted.stream().map(field -> {
                    LandInfo landInfo = new LandInfo();
                    landInfo.setZymj_ys(field.getZymj());
                    landInfo.setZymj_adjusted(field.getZymj());
                    landInfo.setFxId(field.getFxid());
                    return landInfo;
                }).collect(Collectors.toList()), adjustTotal, adjustUnit);
        /**更新占压面积*/
        // 处理空值
        if (com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isNotEmpty(landInfos_adjusted)) {
            landInfos_adjusted.stream().forEach(landInfo_adjusted -> {
                BigDecimal zymjAdjusted = new BigDecimal(landInfo_adjusted.getZymj_adjusted()).setScale(iScale, BigDecimal.ROUND_HALF_UP);
                landInfo_adjusted.setZymj_adjusted(zymjAdjusted.doubleValue());
            });

            /**更新占压数据**/
            sticDlfxTzhService.updateSticByAdjustedInfos(landInfos_adjusted);
        }

    }

}
